package cn.agiledata.bank.audit.service;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import cn.agiledata.bank.account.dao.IAccountDAO;
import cn.agiledata.bank.audit.dao.IAuditGroupDao;
import cn.agiledata.bank.audit.dao.IUserInfoDao;
import cn.agiledata.bank.audit.exception.AuditException;
import cn.agiledata.bank.common.util.Constant;
import cn.agiledata.bank.hibernateBean.Account;
import cn.agiledata.bank.hibernateBean.AuditGroup;
import cn.agiledata.bank.hibernateBean.Operator;
import cn.agiledata.bank.hibernateBean.UserInfo;

/**
 * @author 马贤波
 * 
 */
public final class AuditGroupServiceImpl implements AuditGroupService {
    private IAuditGroupDao auditGroupDao;

    private IAccountDAO accountDao;

    private IUserInfoDao userInfoDao;

    public void setAuditGroupDao(IAuditGroupDao auditGroupDao) {
        this.auditGroupDao = auditGroupDao;
    }

    public void setAccountDao(IAccountDAO accountDao) {
        this.accountDao = accountDao;
    }

    public void setUserInfoDao(IUserInfoDao userInfoDao) {
        this.userInfoDao = userInfoDao;
    }

    public AuditGroup[] getSystemAuditGroupList() {
        return this.auditGroupDao.getAuditGroups(true, null, Boolean.TRUE);
    }

    public AuditGroup[] getUserAuditGroupList(long accountId) {
        return this.auditGroupDao.getAuditGroups(false, new Long(accountId),
                Boolean.TRUE);
    }

    private void setAuditGroup(AuditGroup auditGroup, Account account,
            String name, String remark, long[] auditorIds, String updateUser) {
        if (auditGroup.getAccount() == null)
            auditGroup.setAccount(account);
        auditGroup.setName(name);
        auditGroup.setRemark(remark);
        if (auditorIds != null) {
            Set auditors = new HashSet();
            if (auditGroup.isSystemGroup()) {
                for (int i = 0; i < auditorIds.length; i++) {
                    long auditorId = auditorIds[i];
                    auditors.add(this.userInfoDao.getUserInfoById(auditorId));
                }
                auditGroup.setUsers(auditors);
                auditGroup.setOperators(null);
            } else {
                for (int i = 0; i < auditorIds.length; i++) {
                    Long auditorId = new Long(auditorIds[i]);
                    auditors.add(this.accountDao.getOperatorById(auditorId));
                }
                auditGroup.setOperators(auditors);
                auditGroup.setUsers(null);
            }
        }
        auditGroup.setUpdateUser(updateUser);
        auditGroup.setUpdateTime(new Date());
        if (auditGroup.getCreateUser() == null) {
            auditGroup.setCreateUser(auditGroup.getUpdateUser());
            auditGroup.setCreateTime(auditGroup.getUpdateTime());
        }
    }

    private void checkAuditGroup(boolean systemGroup, Account account,
            Long auditGroupId, String name) throws AuditException {
        if (systemGroup) { // 后台系统审核组才约束名称唯一
            AuditGroup auditGroup = this.auditGroupDao.getAuditGroupByName(
                    systemGroup, account, name);
            if (auditGroup != null && !auditGroup.getId().equals(auditGroupId)) {
                throw AuditException.AUDIT_GROUP_NOT_UNIQUE_NAME;
            }
        }
    }

    private AuditGroup saveOrUpdateAuditGroup(AuditGroup auditGroup,
            Account account, String name, String remark, long[] auditorIds,
            String updateUser) throws AuditException {
        checkAuditGroup(auditGroup.isSystemGroup(), account,
                auditGroup.getId(), name);
        setAuditGroup(auditGroup, account, name, remark, auditorIds, updateUser);
        this.auditGroupDao.saveOrUpdateAuditGroup(auditGroup);
        return auditGroup;
    }

    public AuditGroup addUserAuditGroup(Operator operator, String name,
            String remark, long[] auditors) throws AuditException {
        AuditGroup auditGroup = new AuditGroup(false);
        auditGroup.setUsed(Constant.USED_NO);
        return saveOrUpdateAuditGroup(auditGroup, operator.getAccount(), name,
                remark, auditors, operator.getId().toString());
    }

    public AuditGroup addSystemAuditGroup(UserInfo user, String name,
            String remark, long[] auditors) throws AuditException {
        AuditGroup auditGroup = new AuditGroup(true);
        auditGroup.setUsed(Constant.USED_NO);
        return saveOrUpdateAuditGroup(auditGroup, null, name, remark, auditors,
                user.getId().toString());
    }

    public AuditGroup amendUserAuditGroup(long auditGroupId, Operator operator,
            String name, String remark, long[] auditors) throws AuditException {
        AuditGroup auditGroup = this.auditGroupDao
                .getAuditGroupById(auditGroupId);
        return saveOrUpdateAuditGroup(auditGroup, operator.getAccount(), name,
                remark, auditors, operator.getId().toString());
    }

    public AuditGroup amendSystemAuditGroup(long auditGroupId, UserInfo user,
            String name, String remark, long[] auditors) throws AuditException {
        AuditGroup auditGroup = this.auditGroupDao
                .getAuditGroupById(auditGroupId);
        return saveOrUpdateAuditGroup(auditGroup, null, name, remark, auditors,
                user.getId().toString());
    }

    public boolean removeAuditGroup(long auditGroupId) {
        AuditGroup auditGroup = this.auditGroupDao
                .getAuditGroupById(auditGroupId);
        if (auditGroup.getUsed() == Constant.USED_YES)
            return false;
        this.auditGroupDao.deleteAuditGroup(auditGroup);
        return true;
    }

    public AuditGroup getAuditGroupById(long auditGroupId) {
        return this.auditGroupDao.getAuditGroupById(auditGroupId);
    }
}
